package image.core;
import java.awt.Color;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Arrays;
import java.util.Vector;


public class ImageCoding {
	public static  final String DTC_PATH;
	public static  final String U_PATH;
	public static  final String Y_PATH;
	public static  final String V_PATH;
	static {
		File filePath = new File("");
		DTC_PATH = filePath.getAbsolutePath() + "\\DTC\\";
		U_PATH = filePath.getAbsolutePath() + "\\U\\";
		Y_PATH = filePath.getAbsolutePath() + "\\Y\\";
		V_PATH = filePath.getAbsolutePath() + "\\V\\";
		Arrays.asList(DTC_PATH,U_PATH,Y_PATH,V_PATH).forEach((path)->{
			File file = new File(path);
			if (!file.exists()) file.mkdirs();
		});
	}

	public static Huffman he;
	public  static String strY = "", strU = "", strV = "";
	static ImageInit pr;
	static int w,h;
	public static void encoding(String filePath) {
		pr = new ImageInit(filePath);
		pr.RGB2YUV();
		double[][] matrix = pr.getY();
		w = matrix.length;
		h = matrix[0].length;
		int[][][] winY = PreCoding.encode(matrix, 0);
		matrix = pr.getU();
		int[][][] winU = PreCoding.encode(matrix, 1);
		matrix = pr.getV();
		int[][][] winV = PreCoding.encode(matrix, 1);
		PreCoding.write2File(Y_PATH+"Y_8x8_encoding.txt", winY);
		PreCoding.write2File(U_PATH+"U_8x8_encoding.txt", winU);
		PreCoding.write2File(V_PATH+"V_8x8_encoding.txt", winV);
		
		int[][] Y1d = PreCoding.trs21d(winY);
		int[][] U1d = PreCoding.trs21d(winU);
		int[][] V1d = PreCoding.trs21d(winV);
		PreCoding.write2File(Y_PATH+"Y_1x64_encoding.txt", Y1d);
		PreCoding.write2File(U_PATH+"U_1x64_encoding.txt", U1d);
		PreCoding.write2File(V_PATH+"V_1x64_encoding.txt", V1d);
		//目前为止已经得到了以一维向量呈现的各块数据，接下来应该进行霍夫曼编码
		he = new Huffman();
		for(int i=0; i<Y1d.length; i++) {
			strY += he.LumEncoding(Y1d[i]);
		}
		for(int i=0; i<U1d.length; i++) {
			strU += he.ChrEncoding(U1d[i]);
			strV += he.ChrEncoding(V1d[i]);
		}
	}

	//解码器
	public static void decoding(String filePath,String mime) {
		Vector<int[]> Y1d = new Vector<int[]>();
		Vector<int[]> U1d = new Vector<int[]>();
		Vector<int[]> V1d = new Vector<int[]>();
		while(!strY.equals("")) {
			int[] line = new int[64];
			strY = he.LumDecoding(strY, line);
			Y1d.addElement(line);
		}
		while(!strU.equals("")) {
			int[] line = new int[64];
			strU = he.ChrDecoding(strU, line);
			U1d.addElement(line);
		}
		while(!strV.equals("")) {
			int[] line = new int[64];
			strV = he.ChrDecoding(strV, line);
			V1d.addElement(line);
		}
		PreCoding.write2File(Y_PATH+"Y_1x64_decoding.txt", Y1d);
		PreCoding.write2File(U_PATH+"U_1x64_decoding.txt", U1d);
		PreCoding.write2File(V_PATH+"V_1x64_decoding.txt", V1d);

		/******反Zig-zag编码 将1d数组转化为2d窗格 同时实现DC的差分解码***/
		int[][][] Y2d = PreCoding.trs22d(Y1d);
		int[][][] U2d = PreCoding.trs22d(U1d);
		int[][][] V2d = PreCoding.trs22d(V1d);
		PreCoding.write2File(Y_PATH+"Y_8x8_decoding.txt", Y2d);
		PreCoding.write2File(U_PATH+"U_8x8_decoding.txt", U2d);
		PreCoding.write2File(V_PATH+"V_8x8_decoding.txt", V2d);

		/***********反量化、iDCT 后组合成整块************/
		double[][] Y = PreCoding.decode(Y2d, 0,pr,w,h);
		double[][] U = PreCoding.decode(U2d, 1,pr,w/2,h/2);
		double[][] V = PreCoding.decode(V2d, 1,pr,w/2,h/2);
		PreCoding.write2File(Y_PATH+"Y_256x256_decoding.txt", Y);
		PreCoding.write2File(U_PATH+"U_128x128_decoding.txt", U);
		PreCoding.write2File(V_PATH+"V_128x128_decoding.txt", V);
		Color[][] pic = pr.YUV2RGB(Y, U, V);
		ImageInit.writeImage(pic, filePath, mime);
		
	}
	
	public static void write2File(String fileName, String s) {
		FileOutputStream outSTr = null;
		BufferedOutputStream Buff = null;
		try {
			outSTr = new FileOutputStream(new File(fileName));
			Buff = new BufferedOutputStream(outSTr);
			Buff.write(s.getBytes());
			Buff.flush();
			Buff.close();
		} catch (Exception e) {
			e.printStackTrace(); 
		}
	}
	

}
